package org.jentrata.ebms.messaging; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.ValidationException; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Validates the Camel Message body against a schema(s) * * @author aaronwalker */ public class XmlSchemaValidator implements Processor { public static final String SCHEMA_VALID = "CamelIsSchemaValid"; public static final String SCHEMA_ERRORS = "CamelSchemaErrors"; private static final Logger LOG = LoggerFactory.getLogger(XmlSchemaValidator.class); private SchemaFactory schemaFactory; private Schema schema; public XmlSchemaValidator() { schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); } public XmlSchemaValidator(File schemaFile) throws SAXException { this(); schema = schemaFactory.newSchema(schemaFile); } @Override public void process(Exchange exchange) throws Exception { try { Validator validator = schema.newValidator(); StreamSource source = new StreamSource(exchange.getIn().getBody(InputStream.class)); final List<String> errors = new ArrayList<>(); validator.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) throws SAXException { LOG.debug("Validation warning:" + exception); } @Override public void error(SAXParseException exception) throws SAXException { LOG.warn("Validation error:" + exception); errors.add(exception.getMessage()); } @Override public void fatalError(SAXParseException exception) throws SAXException { LOG.warn("Validation error:" + exception); errors.add(exception.getMessage()); } }); validator.validate(source); if(errors.isEmpty()) { exchange.getIn().setHeader(SCHEMA_VALID,true); } else { exchange.getIn().setHeader(SCHEMA_VALID,false); StringBuilder error = new StringBuilder(); for(String err : errors) { error.append(err + "\n"); } exchange.getIn().setHeader(SCHEMA_ERRORS,error.toString()); throw new ValidationException("Failed Schema Validation:" + error.toString(),exchange,null); } } catch (SAXParseException ex) { throw new ValidationException("Failed Schema Validation:" + ex.getMessage(), exchange, ex); } } public void setSchemaFile(File schemaFile) throws SAXException { schema = schemaFactory.newSchema(schemaFile); } }